package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.aliyuncs.utils.StringUtils;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.domain.Question;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class TanHuaService {
    @Value("${tanhua.default.recommend.users}")
    private String recommendUser;

    @DubboReference
    private RecommendUserApi recommendUserApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private QuestionApi questionApi;
    @DubboReference
    private UserLikeApi userLikeApi;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MessagesService messagesService;
    @DubboReference
    private UserLocationApi userLocationApi;
    @DubboReference
    private VisitorsApi visitorsApi;

    public TodayBest todayBest() {
        //从线程中获取id
        Long userId = UserHolder.getUserId();
        //获取RecommendUser对象,并通过API查询
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(userId);
            recommendUser.setScore(99d);
        }
        //recommendUser转为TodayBest对象
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        return vo;
    }

    /**
     * 推荐朋友
     *
     * @param dto
     * @return
     */
    public PageResult recommendation(RecommendUserDto dto) {
        //从线程中获取id
        Long userId = UserHolder.getUserId();
        //调用recommendUserAPI分页查询数据表
        PageResult pageResult = recommendUserApi.queryrecommendUserList(dto.getPage(), dto.getPagesize(), userId);
        //获取分页中的recommendUser列表
        List<RecommendUser> items = (List<RecommendUser>) pageResult.getItems();
        //判断列表是否为空
        if (items == null || items.size() <= 0) {
            return pageResult;
        }
        List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class);
        UserInfo userInfo = new UserInfo();
        userInfo.setAge(dto.getAge());
        userInfo.setGender(dto.getGender());
        //构造条件，批量查询信息所有用户信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(ids, userInfo);
        //循环推荐列表。构建vo对象
        ArrayList<TodayBest> list = new ArrayList<>();
        for (RecommendUser item : items) {
            UserInfo info = map.get(item.getUserId());
            if (info != null) {
                TodayBest vo = TodayBest.init(info, item);
                list.add(vo);
            }
        }
        //构建返回值
        pageResult.setItems(list);
        return pageResult;
    }

    /**
     * 查看佳人详情
     *
     * @param userId
     * @return
     */
    public TodayBest personalInfo(Long userId) {
        //根据用户id，查询用户详情
        UserInfo userInfo = userInfoApi.findById(userId);
        //根据操作人查询用户的id，查询两人推荐的信息
        RecommendUser recommendUser = recommendUserApi.queryByUserId(userId, UserHolder.getUserId());

        //创建访客条件
        Visitors visitors = new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(recommendUser.getScore());
        visitorsApi.save(visitors);
        //构造返回值
        return TodayBest.init(userInfo, recommendUser);
    }

    /**
     * 查看陌生人问题
     *
     * @param userId
     * @return
     */
    public String findStrangerQuestions(Long userId) {
        //通过用户id直接调用api接口获取问题信息
        Question question = questionApi.findByUserid(userId);
        //如果没有问题 直接利用三元运算符初始一个问题
        return question == null ? "你喜欢摄影吗？" : question.getTxt();
    }

    /**
     * 回复陌生人问题
     *
     * @param userId
     * @param reply
     */
    public void replyQuestions(Long userId, String reply) {
        //获取当前用户的id
        Long userId1 = UserHolder.getUserId();
        //通过id获取用户详情userInfo
        UserInfo userInfo = userInfoApi.findById(userId1);
        //将问题封装到map集合
        Map map = new HashMap();
        map.put("userId", userId1);
        map.put("huanXinId", Constants.HX_USER_PREFIX + userId1);
        map.put("strangerQuestion", findStrangerQuestions(userId));
        map.put("nickname", userInfo.getNickname());
        map.put("reply", reply);
        //将问题转为json格式
        String jsonStringMessage = JSON.toJSONString(map);
        Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, jsonStringMessage);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }
    }

    /**
     * 探花-左滑右滑
     *
     * @return
     */
    public List<TodayBest> queryCardsList() {
        //通过用户id获取10条推荐信息
        List<RecommendUser> users = recommendUserApi.queryCardsList(UserHolder.getUserId(), 10);
        //判断是否有数据
        if (CollUtil.isEmpty(users)) {
            users = new ArrayList<>();
            String[] userIds = recommendUser.split(",");
            for (String userId : userIds) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(userId));
                recommendUser.setToUserId(UserHolder.getUserId());
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                users.add(recommendUser);
            }
        }
        List<Long> userIds = CollUtil.getFieldValues(users, "userId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);

        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser user : users) {
            UserInfo userInfo = map.get(user.getUserId());
            if (userInfo != null) {
                TodayBest vo = TodayBest.init(userInfo, user);
                vos.add(vo);
            }
        }
        return vos;
    }

    /**
     * 探花喜欢
     *
     * @param likeUserId
     */
    public void setLove(Long likeUserId) {
        //保存喜欢的数据
        Boolean aBoolean = userLikeApi.saveOrUpdate(UserHolder.getUserId(), likeUserId, true);
        //判断是否有数据
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }
        //删除不喜欢的数据
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        //从redis中保存喜欢的数据，删除不喜欢的数据
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        //判断是否双向喜欢
        if (isLike(likeUserId, UserHolder.getUserId())) {
            //如果双方都喜欢就添加好友
            messagesService.addContacts(likeUserId);
        }
    }

    /**
     * 判断双方是否都喜欢对方
     *
     * @param userId
     * @param likeUserId
     * @return
     */
    public boolean isLike(Long userId, Long likeUserId) {
        String key = Constants.USER_LIKE_KEY + userId;
        Boolean member = redisTemplate.opsForSet().isMember(key, likeUserId.toString());
        return member;
    }

    /**
     * 探花不喜欢
     *
     * @param notLikeUserId
     */
    public void setUnLove(Long notLikeUserId) {
        //保存喜欢的数据
        Boolean aBoolean = userLikeApi.saveOrUpdate(UserHolder.getUserId(), notLikeUserId, false);
        //判断是否有数据
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }
        //保存不喜欢的用户
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId(), notLikeUserId.toString());
        //从redis中保存不喜欢的数据，删除喜欢的用户
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + UserHolder.getUserId(), notLikeUserId.toString());
        //判断是否双向喜欢
        if (!isLike(UserHolder.getUserId(), notLikeUserId)) {
            //判断是否双方都喜欢，然后进行删除
            messagesService.deleteContacts(notLikeUserId);
        }
    }

    /**
     * 搜附近
     *
     * @param gender
     * @param distance
     * @return
     */
    public List<NearUserVo> search(String gender, String distance) {
        //通过id调用api查询附近的用户
        List<Long> userIds = userLocationApi.search(UserHolder.getUserId(), Double.valueOf(distance));
        //判断附近有无用户
        if (CollUtil.isEmpty(userIds)){
            //如果没有用户就返回新的集合
           return new ArrayList<>();
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(gender);
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, userInfo);

        List<NearUserVo> vos=new ArrayList<>();
        for (Long userId : userIds) {
            //排除当前用户
            if (userId==UserHolder.getUserId()){
                continue;
            }
            UserInfo info = map.get(userId);
            NearUserVo vo = NearUserVo.init(info);
            vos.add(vo);
        }
        return vos;
    }
}
